package com.foxit.pdf2pdf.web.common;

import com.foxit.tbschedule.task.ConversionHistoryInfo;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.query.Query;
import com.google.gson.Gson;
import java.awt.Toolkit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.log4j.Logger;
import org.json.JSONObject;

public class TaskStore
{
  private static final Logger log = Logger.getLogger(TaskStore.class);
  private String conversionType = "pdf2pdf_translation";
  private String cronType;
  private static String tbschedulePatch;// = "http://192.201.108.61:8080/tbschedule/task/receive";
  private String excepireTime_minute = "30";
  private int task_restart_time_minute = 15;
  private int restarts_maximum_number = 20;
  private boolean isRetryTaskTimerStarted = false;
  
  public static String getTbschedulePatch() {
		return tbschedulePatch;
	}
	public static void setTbschedulePatch(String tbschedulePatch) {
		TaskStore.tbschedulePatch = tbschedulePatch;
	}
  Timer timer = new Timer();
  Toolkit toolkit;

  static{
	  init();
  }
  public static void init(){
		try
		{
			  Properties prop = new Properties();
		      InputStream in =  Thread.currentThread().getContextClassLoader().getResourceAsStream("readerConfig.properties");
		      //log.debug(in);
		      prop.load(in);
		      setTbschedulePatch(prop.getProperty("FOXIT_SCHEDUEL_URL").trim());
		      //log.debug("tbschedulePatch:" + getTbschedulePatch());
		}
		catch(Exception ex)
		{
			log.error("Spring initialize failed."+ex);
			return;
		}

  }
  public int getRestarts_maximum_number()
  {
    return this.restarts_maximum_number;
  }

  public void setRestarts_maximum_number(int restarts_maximum_number)
  {
    this.restarts_maximum_number = restarts_maximum_number;
  }

  public boolean pushTask(String documentId, String status, String targetLan,int index,String fileName)
    throws IOException
  {
    //log.debug(documentId + " pushTask start status:" + status);
    if (FXStringUtils.IsNullOrEmpty(this.conversionType)) {
      log.error("Invalid conversion type.");
      return false;
    }
    if (FXStringUtils.IsNullOrEmpty(getTbschedulePatch())) {
      log.error("Invalid url of task receiving service.");
      return false;
    }

    int taskQueueMaxSize = 300;

    PostMethod postMethod = null;
    ByteArrayOutputStream swapStream = new ByteArrayOutputStream();

    HttpClient httpClient = new HttpClient();
    HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
    managerParams.setConnectionTimeout(30000);
    managerParams.setSoTimeout(120000);
    postMethod = new PostMethod(getTbschedulePatch());
    postMethod.addRequestHeader("Content-Type", "application/json");
    TaskBean taskBean = new TaskBean();
    taskBean.setType(this.conversionType);
    HashMap<String,Object> parameterJson = new HashMap<String,Object>();
    Gson gson = new Gson();
    log.debug("TaskStore.pushTask:documentId:" + documentId + ",status:" + status + ",target:" + targetLan + ",index:" + index + ",fileName:" + fileName);
    parameterJson.put("documentId", documentId);
    parameterJson.put("status", status);
    parameterJson.put("target", targetLan);
    parameterJson.put("index", index);
    parameterJson.put("fileName", fileName);
    Map<String,String> parameters = new HashMap<String,String>();

    parameters.put("parameters", Base64.encode(gson.toJson(parameterJson)));

    taskBean.setParameters(parameters);
    String tempStr = gson.toJson(taskBean);
    String[] str = { Base64.encode(gson.toJson(parameterJson)) };

    InputStream in = new ByteArrayInputStream(tempStr.getBytes());
    RequestEntity requestEntity = new InputStreamRequestEntity(in, "text/html;charset=UTF-8");
    postMethod.setRequestEntity(requestEntity);
    try {
      int statusCode = httpClient.executeMethod(postMethod);
      //log.debug("statusCode:" + statusCode);
      if (statusCode != 200) {
        log.error("Tbschedule receives the task failed.");
        return false;
      }
      try {
        String taksReponse = postMethod.getResponseBodyAsString();
        JSONObject jsonObject = null;
        int ret = 1;
        if (!FXStringUtils.IsNullOrEmpty(taksReponse)) {
          jsonObject = new JSONObject(taksReponse);
          ret = jsonObject.getInt("ret");
        }
        if ((jsonObject == null) || (ret != 0)) {
          log.warn("Push task to tbschedule failed, reponse:" + 
            taksReponse);
          return false;
        }
      }
      catch (Exception ex) {
        log.error(ex);
        return false;
      }

      //log.debug(documentId + " pushTask end status:" + status);
      return true;
    } catch (Exception e) {
      log.error(e);
      return false;
    } finally {
      if (postMethod != null)
        postMethod.releaseConnection();
    }
  }

  public void getTaskStatus(String docId)
  {
    MyTask myTask = new MyTask(docId);
    this.timer.schedule(myTask, 1000L, 2000L);
  }

  public class MyTask extends TimerTask
  {
    private String docId = "";
    private int status = 0;

    public MyTask(String docId)
    {
      this.docId = docId;
    }

    public int getStatus()
    {
      return this.status;
    }

    public void run()
    {
      int numWarningBeeps = 3;
      if (numWarningBeeps > 0) {
        TaskStore.this.toolkit.beep();
        System.out.println("Beep!");
        Datastore datastore = GetBean.getDatastore();
        ConversionHistoryInfo taskInfo = (ConversionHistoryInfo)((Query)datastore.createQuery(ConversionHistoryInfo.class).field("_id").equal(Base64.encode(this.docId))).get();
        if (taskInfo != null) {
          this.status = taskInfo.getConversionStatus();
          if (this.status == 4) {
            try {
              int ch = System.in.read();
              if (ch - 99 == 0) {
                TaskStore.this.timer.cancel();
              }

            }
            catch (IOException e)
            {
              e.printStackTrace();
            }
          }
        }
        numWarningBeeps--;
      } else {
        TaskStore.this.toolkit.beep();
        System.out.println("Time's up!");
        System.exit(0);
      }
    }
  }
}